package ginx

import (
	"github.com/go-playground/locales/zh"
	ut "github.com/go-playground/universal-translator"
	"github.com/go-playground/validator/v10"
	zh_translations "github.com/go-playground/validator/v10/translations/zh"
	log "github.com/sirupsen/logrus"
	"path/filepath"
	"reflect"
	"runtime"
	"strings"
)

var validate *validator.Validate
var translator ut.Translator

func init() {
	registerTranslations()
}

func registerTranslations() {
	validate = validator.New()
	uni := ut.New(zh.New())

	var found bool
	translator, found = uni.GetTranslator("zh")
	if found {
		err := zh_translations.RegisterDefaultTranslations(validate, translator)
		if err != nil {
			log.Error(err)
		}
	} else {
		log.Error("Not found translator: zh")
	}

	validate.RegisterTagNameFunc(func(field reflect.StructField) string {
		label := field.Tag.Get("label")
		return label
	})
}

func Validate() *validator.Validate {
	Check(validate)
	return validate
}

func Translator() ut.Translator {
	Check(translator)
	return translator
}

func ValidateStruct(s interface{}) (err error) {
	err = Validate().Struct(s)
	if err != nil {
		_, ok := err.(*validator.InvalidValidationError)
		if ok {
			log.Error("验证错误", err)
		}
		errs, ok := err.(validator.ValidationErrors)
		if ok {
			for _, e := range errs {
				log.Error(e.Translate(Translator()))
			}
		}
		return err
	}
	return nil
}

//结构体指针检查验证，如果传入的interface为nil，就通过log.Panic函数抛出一个异常
//被用在starter中检查公共资源是否被实例化了
func Check(a interface{}) {
	if a == nil {
		_, f, l, _ := runtime.Caller(1)
		strs := strings.Split(f, "/")
		size := len(strs)
		if size > 4 {
			size = 4
		}
		f = filepath.Join(strs[len(strs)-size:]...)
		log.Panicf("object can't be nil, cause by: %s(%d)", f, l)
	}
}

func GetValidationErrors(errs validator.ValidationErrors) string {
	return TransTagName(errs.Translate(Translator()))
}

func TransTagName(err validator.ValidationErrorsTranslations) string {
	var desc []string
	for _, v := range err {
		desc = append(desc, v)
	}
	return strings.Join(desc, "；")
}
